1
|
|
|
var smf_formSubmitted = false; |
2
|
|
|
var lastKeepAliveCheck = new Date().getTime(); |
3
|
|
|
var smf_editorArray = new Array(); |
4
|
|
|
|
5
|
|
|
// Some very basic browser detection - from Mozilla's sniffer page. |
6
|
|
|
var ua = navigator.userAgent.toLowerCase(); |
7
|
|
|
|
8
|
|
|
var is_opera = ua.indexOf('opera') != -1; |
9
|
|
|
var is_ff = (ua.indexOf('firefox') != -1 || ua.indexOf('iceweasel') != -1 || ua.indexOf('icecat') != -1 || ua.indexOf('shiretoko') != -1 || ua.indexOf('minefield') != -1) && !is_opera; |
10
|
|
|
var is_gecko = ua.indexOf('gecko') != -1 && !is_opera; |
11
|
|
|
|
12
|
|
|
var is_chrome = ua.indexOf('chrome') != -1; |
13
|
|
|
var is_safari = ua.indexOf('applewebkit') != -1 && !is_chrome; |
14
|
|
|
var is_webkit = ua.indexOf('applewebkit') != -1; |
15
|
|
|
|
16
|
|
|
var is_ie = ua.indexOf('msie') != -1 && !is_opera; |
17
|
|
|
// Stupid Microsoft... |
18
|
|
|
var is_ie11 = ua.indexOf('trident') != -1 && ua.indexOf('gecko') != -1; |
19
|
|
|
var is_iphone = ua.indexOf('iphone') != -1 || ua.indexOf('ipod') != -1; |
20
|
|
|
var is_android = ua.indexOf('android') != -1; |
21
|
|
|
|
22
|
|
|
var ajax_indicator_ele = null; |
23
|
|
|
|
24
|
|
|
// Some older versions of Mozilla don't have this, for some reason. |
25
|
|
|
if (!('forms' in document)) |
26
|
|
|
document.forms = document.getElementsByTagName('form'); |
27
|
|
|
|
28
|
|
|
// Versions of ie < 9 do not have this built in |
29
|
|
|
if (!('getElementsByClassName' in document)) |
30
|
|
|
{ |
31
|
|
|
document.getElementsByClassName = function(className) |
32
|
|
|
{ |
33
|
|
|
return $('".' + className + '"'); |
34
|
|
|
} |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
// Get a response from the server. |
38
|
|
|
function getServerResponse(sUrl, funcCallback, sType, sDataType) |
39
|
|
|
{ |
40
|
|
|
var oCaller = this; |
41
|
|
|
var oMyDoc = $.ajax({ |
42
|
|
|
type: sType, |
43
|
|
|
url: sUrl, |
44
|
|
|
cache: false, |
45
|
|
|
dataType: sDataType, |
46
|
|
|
success: function(response) { |
47
|
|
|
if (typeof(funcCallback) != 'undefined') |
48
|
|
|
{ |
49
|
|
|
funcCallback.call(oCaller, response); |
50
|
|
|
} |
51
|
|
|
}, |
52
|
|
|
}); |
53
|
|
|
|
54
|
|
|
return oMyDoc; |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
// Load an XML document. |
58
|
|
|
function getXMLDocument(sUrl, funcCallback) |
59
|
|
|
{ |
60
|
|
|
var oCaller = this; |
61
|
|
|
var oMyDoc = $.ajax({ |
62
|
|
|
type: 'GET', |
63
|
|
|
url: sUrl, |
64
|
|
|
cache: false, |
65
|
|
|
dataType: 'xml', |
66
|
|
|
success: function(responseXML) { |
67
|
|
|
if (typeof(funcCallback) != 'undefined') |
68
|
|
|
{ |
69
|
|
|
funcCallback.call(oCaller, responseXML); |
70
|
|
|
} |
71
|
|
|
}, |
72
|
|
|
}); |
73
|
|
|
|
74
|
|
|
return oMyDoc; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
// Send a post form to the server. |
78
|
|
|
function sendXMLDocument(sUrl, sContent, funcCallback) |
79
|
|
|
{ |
80
|
|
|
var oCaller = this; |
81
|
|
|
var oSendDoc = $.ajax({ |
|
|
|
|
82
|
|
|
type: 'POST', |
83
|
|
|
url: sUrl, |
84
|
|
|
data: sContent, |
85
|
|
|
beforeSend: function(xhr) { |
86
|
|
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); |
87
|
|
|
}, |
88
|
|
|
dataType: 'xml', |
89
|
|
|
success: function(responseXML) { |
90
|
|
|
if (typeof(funcCallback) != 'undefined') |
91
|
|
|
{ |
92
|
|
|
funcCallback.call(oCaller, responseXML); |
93
|
|
|
} |
94
|
|
|
}, |
95
|
|
|
}); |
96
|
|
|
|
97
|
|
|
return true; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
// A property we'll be needing for php_to8bit. |
101
|
|
|
String.prototype.oCharsetConversion = { |
|
|
|
|
102
|
|
|
from: '', |
103
|
|
|
to: '' |
104
|
|
|
}; |
105
|
|
|
|
106
|
|
|
// Convert a string to an 8 bit representation (like in PHP). |
107
|
|
|
String.prototype.php_to8bit = function () |
|
|
|
|
108
|
|
|
{ |
109
|
|
|
if (smf_charset == 'UTF-8') |
110
|
|
|
{ |
111
|
|
|
var n, sReturn = ''; |
112
|
|
|
|
113
|
|
|
for (var i = 0, iTextLen = this.length; i < iTextLen; i++) |
114
|
|
|
{ |
115
|
|
|
n = this.charCodeAt(i); |
116
|
|
|
if (n < 128) |
117
|
|
|
sReturn += String.fromCharCode(n); |
118
|
|
|
else if (n < 2048) |
119
|
|
|
sReturn += String.fromCharCode(192 | n >> 6) + String.fromCharCode(128 | n & 63); |
120
|
|
|
else if (n < 65536) |
121
|
|
|
sReturn += String.fromCharCode(224 | n >> 12) + String.fromCharCode(128 | n >> 6 & 63) + String.fromCharCode(128 | n & 63); |
122
|
|
|
else |
123
|
|
|
sReturn += String.fromCharCode(240 | n >> 18) + String.fromCharCode(128 | n >> 12 & 63) + String.fromCharCode(128 | n >> 6 & 63) + String.fromCharCode(128 | n & 63); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
return sReturn; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
else if (this.oCharsetConversion.from.length == 0) |
130
|
|
|
{ |
131
|
|
|
switch (smf_charset) |
132
|
|
|
{ |
133
|
|
|
case 'ISO-8859-1': |
134
|
|
|
this.oCharsetConversion = { |
135
|
|
|
from: '\xa0-\xff', |
136
|
|
|
to: '\xa0-\xff' |
137
|
|
|
}; |
138
|
|
|
break; |
139
|
|
|
|
140
|
|
|
case 'ISO-8859-2': |
141
|
|
|
this.oCharsetConversion = { |
142
|
|
|
from: '\xa0\u0104\u02d8\u0141\xa4\u013d\u015a\xa7\xa8\u0160\u015e\u0164\u0179\xad\u017d\u017b\xb0\u0105\u02db\u0142\xb4\u013e\u015b\u02c7\xb8\u0161\u015f\u0165\u017a\u02dd\u017e\u017c\u0154\xc1\xc2\u0102\xc4\u0139\u0106\xc7\u010c\xc9\u0118\xcb\u011a\xcd\xce\u010e\u0110\u0143\u0147\xd3\xd4\u0150\xd6\xd7\u0158\u016e\xda\u0170\xdc\xdd\u0162\xdf\u0155\xe1\xe2\u0103\xe4\u013a\u0107\xe7\u010d\xe9\u0119\xeb\u011b\xed\xee\u010f\u0111\u0144\u0148\xf3\xf4\u0151\xf6\xf7\u0159\u016f\xfa\u0171\xfc\xfd\u0163\u02d9', |
143
|
|
|
to: '\xa0-\xff' |
144
|
|
|
}; |
145
|
|
|
break; |
146
|
|
|
|
147
|
|
|
case 'ISO-8859-5': |
148
|
|
|
this.oCharsetConversion = { |
149
|
|
|
from: '\xa0\u0401-\u040c\xad\u040e-\u044f\u2116\u0451-\u045c\xa7\u045e\u045f', |
150
|
|
|
to: '\xa0-\xff' |
151
|
|
|
}; |
152
|
|
|
break; |
153
|
|
|
|
154
|
|
|
case 'ISO-8859-9': |
155
|
|
|
this.oCharsetConversion = { |
156
|
|
|
from: '\xa0-\xcf\u011e\xd1-\xdc\u0130\u015e\xdf-\xef\u011f\xf1-\xfc\u0131\u015f\xff', |
157
|
|
|
to: '\xa0-\xff' |
158
|
|
|
}; |
159
|
|
|
break; |
160
|
|
|
|
161
|
|
|
case 'ISO-8859-15': |
162
|
|
|
this.oCharsetConversion = { |
163
|
|
|
from: '\xa0-\xa3\u20ac\xa5\u0160\xa7\u0161\xa9-\xb3\u017d\xb5-\xb7\u017e\xb9-\xbb\u0152\u0153\u0178\xbf-\xff', |
164
|
|
|
to: '\xa0-\xff' |
165
|
|
|
}; |
166
|
|
|
break; |
167
|
|
|
|
168
|
|
|
case 'tis-620': |
169
|
|
|
this.oCharsetConversion = { |
170
|
|
|
from: '\u20ac\u2026\u2018\u2019\u201c\u201d\u2022\u2013\u2014\xa0\u0e01-\u0e3a\u0e3f-\u0e5b', |
171
|
|
|
to: '\x80\x85\x91-\x97\xa0-\xda\xdf-\xfb' |
172
|
|
|
}; |
173
|
|
|
break; |
174
|
|
|
|
175
|
|
|
case 'windows-1251': |
176
|
|
|
this.oCharsetConversion = { |
177
|
|
|
from: '\u0402\u0403\u201a\u0453\u201e\u2026\u2020\u2021\u20ac\u2030\u0409\u2039\u040a\u040c\u040b\u040f\u0452\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u2122\u0459\u203a\u045a\u045c\u045b\u045f\xa0\u040e\u045e\u0408\xa4\u0490\xa6\xa7\u0401\xa9\u0404\xab-\xae\u0407\xb0\xb1\u0406\u0456\u0491\xb5-\xb7\u0451\u2116\u0454\xbb\u0458\u0405\u0455\u0457\u0410-\u044f', |
178
|
|
|
to: '\x80-\x97\x99-\xff' |
179
|
|
|
}; |
180
|
|
|
break; |
181
|
|
|
|
182
|
|
|
case 'windows-1253': |
183
|
|
|
this.oCharsetConversion = { |
184
|
|
|
from: '\u20ac\u201a\u0192\u201e\u2026\u2020\u2021\u2030\u2039\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u2122\u203a\xa0\u0385\u0386\xa3-\xa9\xab-\xae\u2015\xb0-\xb3\u0384\xb5-\xb7\u0388-\u038a\xbb\u038c\xbd\u038e-\u03a1\u03a3-\u03ce', |
185
|
|
|
to: '\x80\x82-\x87\x89\x8b\x91-\x97\x99\x9b\xa0-\xa9\xab-\xd1\xd3-\xfe' |
186
|
|
|
}; |
187
|
|
|
break; |
188
|
|
|
|
189
|
|
|
case 'windows-1255': |
190
|
|
|
this.oCharsetConversion = { |
191
|
|
|
from: '\u20ac\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u2039\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u02dc\u2122\u203a\xa0-\xa3\u20aa\xa5-\xa9\xd7\xab-\xb9\xf7\xbb-\xbf\u05b0-\u05b9\u05bb-\u05c3\u05f0-\u05f4\u05d0-\u05ea\u200e\u200f', |
192
|
|
|
to: '\x80\x82-\x89\x8b\x91-\x99\x9b\xa0-\xc9\xcb-\xd8\xe0-\xfa\xfd\xfe' |
193
|
|
|
}; |
194
|
|
|
break; |
195
|
|
|
|
196
|
|
|
case 'windows-1256': |
197
|
|
|
this.oCharsetConversion = { |
198
|
|
|
from: '\u20ac\u067e\u201a\u0192\u201e\u2026\u2020\u2021\u02c6\u2030\u0679\u2039\u0152\u0686\u0698\u0688\u06af\u2018\u2019\u201c\u201d\u2022\u2013\u2014\u06a9\u2122\u0691\u203a\u0153\u200c\u200d\u06ba\xa0\u060c\xa2-\xa9\u06be\xab-\xb9\u061b\xbb-\xbe\u061f\u06c1\u0621-\u0636\xd7\u0637-\u063a\u0640-\u0643\xe0\u0644\xe2\u0645-\u0648\xe7-\xeb\u0649\u064a\xee\xef\u064b-\u064e\xf4\u064f\u0650\xf7\u0651\xf9\u0652\xfb\xfc\u200e\u200f\u06d2', |
199
|
|
|
to: '\x80-\xff' |
200
|
|
|
}; |
201
|
|
|
break; |
202
|
|
|
|
203
|
|
|
default: |
204
|
|
|
this.oCharsetConversion = { |
205
|
|
|
from: '', |
206
|
|
|
to: '' |
207
|
|
|
}; |
208
|
|
|
break; |
209
|
|
|
} |
210
|
|
|
var funcExpandString = function (sSearch) { |
211
|
|
|
var sInsert = ''; |
212
|
|
|
for (var i = sSearch.charCodeAt(0), n = sSearch.charCodeAt(2); i <= n; i++) |
213
|
|
|
sInsert += String.fromCharCode(i); |
214
|
|
|
return sInsert; |
215
|
|
|
}; |
216
|
|
|
this.oCharsetConversion.from = this.oCharsetConversion.from.replace(/.\-./g, funcExpandString); |
217
|
|
|
this.oCharsetConversion.to = this.oCharsetConversion.to.replace(/.\-./g, funcExpandString); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
var sReturn = '', iOffsetFrom = 0; |
|
|
|
|
221
|
|
|
for (var i = 0, n = this.length; i < n; i++) |
|
|
|
|
222
|
|
|
{ |
223
|
|
|
iOffsetFrom = this.oCharsetConversion.from.indexOf(this.charAt(i)); |
224
|
|
|
sReturn += iOffsetFrom > -1 ? this.oCharsetConversion.to.charAt(iOffsetFrom) : (this.charCodeAt(i) > 127 ? '&#' + this.charCodeAt(i) + ';' : this.charAt(i)); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
return sReturn |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
// Character-level replacement function. |
231
|
|
|
String.prototype.php_strtr = function (sFrom, sTo) |
|
|
|
|
232
|
|
|
{ |
233
|
|
|
return this.replace(new RegExp('[' + sFrom + ']', 'g'), function (sMatch) { |
234
|
|
|
return sTo.charAt(sFrom.indexOf(sMatch)); |
235
|
|
|
}); |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
// Simulate PHP's strtolower (in SOME cases PHP uses ISO-8859-1 case folding). |
239
|
|
|
String.prototype.php_strtolower = function () |
|
|
|
|
240
|
|
|
{ |
241
|
|
|
return typeof(smf_iso_case_folding) == 'boolean' && smf_iso_case_folding == true ? this.php_strtr( |
242
|
|
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZ\x8a\x8c\x8e\x9f\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde', |
243
|
|
|
'abcdefghijklmnopqrstuvwxyz\x9a\x9c\x9e\xff\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe' |
244
|
|
|
) : this.php_strtr('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
String.prototype.php_urlencode = function() |
|
|
|
|
248
|
|
|
{ |
249
|
|
|
return escape(this).replace(/\+/g, '%2b').replace('*', '%2a').replace('/', '%2f').replace('@', '%40'); |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
String.prototype.php_htmlspecialchars = function() |
|
|
|
|
253
|
|
|
{ |
254
|
|
|
return this.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
String.prototype.php_unhtmlspecialchars = function() |
|
|
|
|
258
|
|
|
{ |
259
|
|
|
return this.replace(/"/g, '"').replace(/>/g, '>').replace(/</g, '<').replace(/&/g, '&'); |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
String.prototype.php_addslashes = function() |
|
|
|
|
263
|
|
|
{ |
264
|
|
|
return this.replace(/\\/g, '\\\\').replace(/'/g, '\\\''); |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
String.prototype._replaceEntities = function(sInput, sDummy, sNum) |
|
|
|
|
268
|
|
|
{ |
269
|
|
|
return String.fromCharCode(parseInt(sNum)); |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
String.prototype.removeEntities = function() |
|
|
|
|
273
|
|
|
{ |
274
|
|
|
return this.replace(/&(amp;)?#(\d+);/g, this._replaceEntities); |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
String.prototype.easyReplace = function (oReplacements) |
|
|
|
|
278
|
|
|
{ |
279
|
|
|
var sResult = this; |
280
|
|
|
for (var sSearch in oReplacements) |
|
|
|
|
281
|
|
|
sResult = sResult.replace(new RegExp('%' + sSearch + '%', 'g'), oReplacements[sSearch]); |
282
|
|
|
|
283
|
|
|
return sResult; |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
// Open a new window |
287
|
|
|
function reqWin(desktopURL, alternateWidth, alternateHeight, noScrollbars) |
288
|
|
|
{ |
289
|
|
|
if ((alternateWidth && self.screen.availWidth * 0.8 < alternateWidth) || (alternateHeight && self.screen.availHeight * 0.8 < alternateHeight)) |
290
|
|
|
{ |
291
|
|
|
noScrollbars = false; |
292
|
|
|
alternateWidth = Math.min(alternateWidth, self.screen.availWidth * 0.8); |
293
|
|
|
alternateHeight = Math.min(alternateHeight, self.screen.availHeight * 0.8); |
294
|
|
|
} |
295
|
|
|
else |
296
|
|
|
noScrollbars = typeof(noScrollbars) == 'boolean' && noScrollbars == true; |
297
|
|
|
|
298
|
|
|
window.open(desktopURL, 'requested_popup', 'toolbar=no,location=no,status=no,menubar=no,scrollbars=' + (noScrollbars ? 'no' : 'yes') + ',width=' + (alternateWidth ? alternateWidth : 480) + ',height=' + (alternateHeight ? alternateHeight : 220) + ',resizable=no'); |
299
|
|
|
|
300
|
|
|
// Return false so the click won't follow the link ;). |
301
|
|
|
return false; |
302
|
|
|
} |
303
|
|
|
|
304
|
|
|
// Open a overlay div |
305
|
|
|
function reqOverlayDiv(desktopURL, sHeader, sIcon) |
306
|
|
|
{ |
307
|
|
|
// Set up our div details |
308
|
|
|
var sAjax_indicator = '<div class="centertext"><img src="' + smf_images_url + '/loading_sm.gif"></div>'; |
309
|
|
|
var sIcon = smf_images_url + '/' + (typeof(sIcon) == 'string' ? sIcon : 'helptopics.png'); |
310
|
|
|
var sHeader = typeof(sHeader) == 'string' ? sHeader : help_popup_heading_text; |
311
|
|
|
|
312
|
|
|
// Create the div that we are going to load |
313
|
|
|
var oContainer = new smc_Popup({heading: sHeader, content: sAjax_indicator, icon: sIcon}); |
|
|
|
|
314
|
|
|
var oPopup_body = $('#' + oContainer.popup_id).find('.popup_content'); |
315
|
|
|
|
316
|
|
|
// Load the help page content (we just want the text to show) |
317
|
|
|
$.ajax({ |
318
|
|
|
url: desktopURL, |
319
|
|
|
type: "GET", |
320
|
|
|
dataType: "html", |
321
|
|
|
beforeSend: function () { |
322
|
|
|
}, |
323
|
|
|
success: function (data, textStatus, xhr) { |
|
|
|
|
324
|
|
|
var help_content = $('<div id="temp_help">').html(data).find('a[href$="self.close();"]').hide().prev('br').hide().parent().html(); |
325
|
|
|
oPopup_body.html(help_content); |
326
|
|
|
}, |
327
|
|
|
error: function (xhr, textStatus, errorThrown) { |
|
|
|
|
328
|
|
|
oPopup_body.html(textStatus); |
329
|
|
|
} |
330
|
|
|
}); |
331
|
|
|
return false; |
332
|
|
|
} |
333
|
|
|
|
334
|
|
|
// Create the popup menus for the top level/user menu area. |
335
|
|
|
function smc_PopupMenu(oOptions) |
336
|
|
|
{ |
337
|
|
|
this.opt = (typeof oOptions == 'object') ? oOptions : {}; |
338
|
|
|
this.opt.menus = {}; |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
smc_PopupMenu.prototype.add = function (sItem, sUrl) |
342
|
|
|
{ |
343
|
|
|
var $menu = $('#' + sItem + '_menu'), $item = $('#' + sItem + '_menu_top'); |
344
|
|
|
if ($item.length == 0) |
345
|
|
|
return; |
346
|
|
|
|
347
|
|
|
this.opt.menus[sItem] = {open: false, loaded: false, sUrl: sUrl, itemObj: $item, menuObj: $menu }; |
348
|
|
|
|
349
|
|
|
$item.click({obj: this}, function (e) { |
350
|
|
|
e.preventDefault(); |
351
|
|
|
|
352
|
|
|
e.data.obj.toggle(sItem); |
353
|
|
|
}); |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
smc_PopupMenu.prototype.toggle = function (sItem) |
357
|
|
|
{ |
358
|
|
|
if (!!this.opt.menus[sItem].open) |
359
|
|
|
this.close(sItem); |
360
|
|
|
else |
361
|
|
|
this.open(sItem); |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
smc_PopupMenu.prototype.open = function (sItem) |
365
|
|
|
{ |
366
|
|
|
this.closeAll(); |
367
|
|
|
|
368
|
|
|
if (!this.opt.menus[sItem].loaded) |
369
|
|
|
{ |
370
|
|
|
this.opt.menus[sItem].menuObj.html('<div class="loading">' + (typeof(ajax_notification_text) != null ? ajax_notification_text : '') + '</div>'); |
371
|
|
|
this.opt.menus[sItem].menuObj.load(this.opt.menus[sItem].sUrl, function() { |
372
|
|
|
if ($(this).hasClass('scrollable')) |
373
|
|
|
$(this).customScrollbar({ |
374
|
|
|
skin: "default-skin", |
375
|
|
|
hScroll: false, |
376
|
|
|
updateOnWindowResize: true |
377
|
|
|
}); |
378
|
|
|
}); |
379
|
|
|
this.opt.menus[sItem].loaded = true; |
380
|
|
|
} |
381
|
|
|
|
382
|
|
|
this.opt.menus[sItem].menuObj.addClass('visible'); |
383
|
|
|
this.opt.menus[sItem].itemObj.addClass('open'); |
384
|
|
|
this.opt.menus[sItem].open = true; |
385
|
|
|
|
386
|
|
|
// Now set up closing the menu if we click off. |
387
|
|
|
$(document).on('click.menu', {obj: this}, function(e) { |
388
|
|
|
if ($(e.target).closest(e.data.obj.opt.menus[sItem].menuObj.parent()).length) |
389
|
|
|
return; |
390
|
|
|
e.data.obj.closeAll(); |
391
|
|
|
$(document).off('click.menu'); |
392
|
|
|
}); |
393
|
|
|
} |
394
|
|
|
|
395
|
|
|
smc_PopupMenu.prototype.close = function (sItem) |
396
|
|
|
{ |
397
|
|
|
this.opt.menus[sItem].menuObj.removeClass('visible'); |
398
|
|
|
this.opt.menus[sItem].itemObj.removeClass('open'); |
399
|
|
|
this.opt.menus[sItem].open = false; |
400
|
|
|
$(document).off('click.menu'); |
401
|
|
|
} |
402
|
|
|
|
403
|
|
|
smc_PopupMenu.prototype.closeAll = function () |
404
|
|
|
{ |
405
|
|
|
for (var prop in this.opt.menus) |
|
|
|
|
406
|
|
|
if (!!this.opt.menus[prop].open) |
407
|
|
|
this.close(prop); |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
// *** smc_Popup class. |
411
|
|
|
function smc_Popup(oOptions) |
412
|
|
|
{ |
413
|
|
|
this.opt = oOptions; |
414
|
|
|
this.popup_id = this.opt.custom_id ? this.opt.custom_id : 'smf_popup'; |
415
|
|
|
this.show(); |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
smc_Popup.prototype.show = function () |
419
|
|
|
{ |
420
|
|
|
popup_class = 'popup_window ' + (this.opt.custom_class ? this.opt.custom_class : 'description'); |
|
|
|
|
421
|
|
|
if (this.opt.icon_class) |
422
|
|
|
icon = '<span class="' + this.opt.icon_class + '"></span> '; |
|
|
|
|
423
|
|
|
else |
424
|
|
|
icon = this.opt.icon ? '<img src="' + this.opt.icon + '" class="icon" alt=""> ' : ''; |
425
|
|
|
|
426
|
|
|
// Create the div that will be shown |
427
|
|
|
$('body').append('<div id="' + this.popup_id + '" class="popup_container"><div class="' + popup_class + '"><div class="catbg popup_heading"><a href="javascript:void(0);" class="generic_icons hide_popup"></a>' + icon + this.opt.heading + '</div><div class="popup_content">' + this.opt.content + '</div></div></div>'); |
428
|
|
|
|
429
|
|
|
// Show it |
430
|
|
|
this.popup_body = $('#' + this.popup_id).children('.popup_window'); |
431
|
|
|
this.popup_body.parent().fadeIn(300); |
432
|
|
|
|
433
|
|
|
// Trigger hide on escape or mouse click |
434
|
|
|
var popup_instance = this; |
435
|
|
|
$(document).mouseup(function (e) { |
436
|
|
|
if ($('#' + popup_instance.popup_id).has(e.target).length === 0) |
437
|
|
|
popup_instance.hide(); |
438
|
|
|
}).keyup(function(e){ |
439
|
|
|
if (e.keyCode == 27) |
440
|
|
|
popup_instance.hide(); |
441
|
|
|
}); |
442
|
|
|
$('#' + this.popup_id).find('.hide_popup').click(function (){ return popup_instance.hide(); }); |
443
|
|
|
|
444
|
|
|
return false; |
445
|
|
|
} |
446
|
|
|
|
447
|
|
|
smc_Popup.prototype.hide = function () |
448
|
|
|
{ |
449
|
|
|
$('#' + this.popup_id).fadeOut(300, function(){ $(this).remove(); }); |
450
|
|
|
|
451
|
|
|
return false; |
452
|
|
|
} |
453
|
|
|
|
454
|
|
|
// Remember the current position. |
455
|
|
|
function storeCaret(oTextHandle) |
456
|
|
|
{ |
457
|
|
|
// Only bother if it will be useful. |
458
|
|
|
if ('createTextRange' in oTextHandle) |
459
|
|
|
oTextHandle.caretPos = document.selection.createRange().duplicate(); |
460
|
|
|
} |
461
|
|
|
|
462
|
|
|
// Replaces the currently selected text with the passed text. |
463
|
|
|
function replaceText(text, oTextHandle) |
464
|
|
|
{ |
465
|
|
|
// Attempt to create a text range (IE). |
466
|
|
|
if ('caretPos' in oTextHandle && 'createTextRange' in oTextHandle) |
467
|
|
|
{ |
468
|
|
|
var caretPos = oTextHandle.caretPos; |
469
|
|
|
|
470
|
|
|
caretPos.text = caretPos.text.charAt(caretPos.text.length - 1) == ' ' ? text + ' ' : text; |
471
|
|
|
caretPos.select(); |
472
|
|
|
} |
473
|
|
|
// Mozilla text range replace. |
474
|
|
|
else if ('selectionStart' in oTextHandle) |
475
|
|
|
{ |
476
|
|
|
var begin = oTextHandle.value.substr(0, oTextHandle.selectionStart); |
477
|
|
|
var end = oTextHandle.value.substr(oTextHandle.selectionEnd); |
478
|
|
|
var scrollPos = oTextHandle.scrollTop; |
479
|
|
|
|
480
|
|
|
oTextHandle.value = begin + text + end; |
481
|
|
|
|
482
|
|
|
if (oTextHandle.setSelectionRange) |
483
|
|
|
{ |
484
|
|
|
oTextHandle.focus(); |
485
|
|
|
var goForward = is_opera ? text.match(/\n/g).length : 0; |
486
|
|
|
oTextHandle.setSelectionRange(begin.length + text.length + goForward, begin.length + text.length + goForward); |
487
|
|
|
} |
488
|
|
|
oTextHandle.scrollTop = scrollPos; |
489
|
|
|
} |
490
|
|
|
// Just put it on the end. |
491
|
|
|
else |
492
|
|
|
{ |
493
|
|
|
oTextHandle.value += text; |
494
|
|
|
oTextHandle.focus(oTextHandle.value.length - 1); |
495
|
|
|
} |
496
|
|
|
} |
497
|
|
|
|
498
|
|
|
// Surrounds the selected text with text1 and text2. |
499
|
|
|
function surroundText(text1, text2, oTextHandle) |
500
|
|
|
{ |
501
|
|
|
// Can a text range be created? |
502
|
|
|
if ('caretPos' in oTextHandle && 'createTextRange' in oTextHandle) |
503
|
|
|
{ |
504
|
|
|
var caretPos = oTextHandle.caretPos, temp_length = caretPos.text.length; |
505
|
|
|
|
506
|
|
|
caretPos.text = caretPos.text.charAt(caretPos.text.length - 1) == ' ' ? text1 + caretPos.text + text2 + ' ' : text1 + caretPos.text + text2; |
507
|
|
|
|
508
|
|
|
if (temp_length == 0) |
509
|
|
|
{ |
510
|
|
|
caretPos.moveStart('character', -text2.length); |
511
|
|
|
caretPos.moveEnd('character', -text2.length); |
512
|
|
|
caretPos.select(); |
513
|
|
|
} |
514
|
|
|
else |
515
|
|
|
oTextHandle.focus(caretPos); |
516
|
|
|
} |
517
|
|
|
// Mozilla text range wrap. |
518
|
|
|
else if ('selectionStart' in oTextHandle) |
519
|
|
|
{ |
520
|
|
|
var begin = oTextHandle.value.substr(0, oTextHandle.selectionStart); |
521
|
|
|
var selection = oTextHandle.value.substr(oTextHandle.selectionStart, oTextHandle.selectionEnd - oTextHandle.selectionStart); |
522
|
|
|
var end = oTextHandle.value.substr(oTextHandle.selectionEnd); |
523
|
|
|
var newCursorPos = oTextHandle.selectionStart; |
524
|
|
|
var scrollPos = oTextHandle.scrollTop; |
525
|
|
|
|
526
|
|
|
oTextHandle.value = begin + text1 + selection + text2 + end; |
527
|
|
|
|
528
|
|
|
if (oTextHandle.setSelectionRange) |
529
|
|
|
{ |
530
|
|
|
var goForward = is_opera ? text1.match(/\n/g).length : 0, goForwardAll = is_opera ? (text1 + text2).match(/\n/g).length : 0; |
531
|
|
|
if (selection.length == 0) |
532
|
|
|
oTextHandle.setSelectionRange(newCursorPos + text1.length + goForward, newCursorPos + text1.length + goForward); |
533
|
|
|
else |
534
|
|
|
oTextHandle.setSelectionRange(newCursorPos, newCursorPos + text1.length + selection.length + text2.length + goForwardAll); |
535
|
|
|
oTextHandle.focus(); |
536
|
|
|
} |
537
|
|
|
oTextHandle.scrollTop = scrollPos; |
538
|
|
|
} |
539
|
|
|
// Just put them on the end, then. |
540
|
|
|
else |
541
|
|
|
{ |
542
|
|
|
oTextHandle.value += text1 + text2; |
543
|
|
|
oTextHandle.focus(oTextHandle.value.length - 1); |
544
|
|
|
} |
545
|
|
|
} |
546
|
|
|
|
547
|
|
|
// Checks if the passed input's value is nothing. |
548
|
|
|
function isEmptyText(theField) |
549
|
|
|
{ |
550
|
|
|
// Copy the value so changes can be made.. |
551
|
|
|
if (typeof(theField) == 'string') |
552
|
|
|
var theValue = theField; |
553
|
|
|
else |
554
|
|
|
var theValue = theField.value; |
|
|
|
|
555
|
|
|
|
556
|
|
|
// Strip whitespace off the left side. |
557
|
|
|
while (theValue.length > 0 && (theValue.charAt(0) == ' ' || theValue.charAt(0) == '\t')) |
558
|
|
|
theValue = theValue.substring(1, theValue.length); |
559
|
|
|
// Strip whitespace off the right side. |
560
|
|
|
while (theValue.length > 0 && (theValue.charAt(theValue.length - 1) == ' ' || theValue.charAt(theValue.length - 1) == '\t')) |
561
|
|
|
theValue = theValue.substring(0, theValue.length - 1); |
562
|
|
|
|
563
|
|
|
if (theValue == '') |
564
|
|
|
return true; |
565
|
|
|
else |
566
|
|
|
return false; |
567
|
|
|
} |
568
|
|
|
|
569
|
|
|
// Only allow form submission ONCE. |
570
|
|
|
function submitonce(theform) |
|
|
|
|
571
|
|
|
{ |
572
|
|
|
smf_formSubmitted = true; |
573
|
|
|
|
574
|
|
|
// If there are any editors warn them submit is coming! |
575
|
|
|
for (var i = 0; i < smf_editorArray.length; i++) |
576
|
|
|
smf_editorArray[i].doSubmit(); |
577
|
|
|
} |
578
|
|
|
function submitThisOnce(oControl) |
579
|
|
|
{ |
580
|
|
|
// oControl might also be a form. |
581
|
|
|
var oForm = 'form' in oControl ? oControl.form : oControl; |
582
|
|
|
|
583
|
|
|
var aTextareas = oForm.getElementsByTagName('textarea'); |
584
|
|
|
for (var i = 0, n = aTextareas.length; i < n; i++) |
585
|
|
|
aTextareas[i].readOnly = true; |
586
|
|
|
|
587
|
|
|
return !smf_formSubmitted; |
588
|
|
|
} |
589
|
|
|
|
590
|
|
|
// Deprecated, as innerHTML is supported everywhere. |
591
|
|
|
function setInnerHTML(oElement, sToValue) |
592
|
|
|
{ |
593
|
|
|
oElement.innerHTML = sToValue; |
594
|
|
|
} |
595
|
|
|
|
596
|
|
|
function getInnerHTML(oElement) |
597
|
|
|
{ |
598
|
|
|
return oElement.innerHTML; |
599
|
|
|
} |
600
|
|
|
|
601
|
|
|
// Set the "outer" HTML of an element. |
602
|
|
|
function setOuterHTML(oElement, sToValue) |
603
|
|
|
{ |
604
|
|
|
if ('outerHTML' in oElement) |
605
|
|
|
oElement.outerHTML = sToValue; |
606
|
|
|
else |
607
|
|
|
{ |
608
|
|
|
var range = document.createRange(); |
609
|
|
|
range.setStartBefore(oElement); |
610
|
|
|
oElement.parentNode.replaceChild(range.createContextualFragment(sToValue), oElement); |
611
|
|
|
} |
612
|
|
|
} |
613
|
|
|
|
614
|
|
|
// Checks for variable in theArray. |
615
|
|
|
function in_array(variable, theArray) |
616
|
|
|
{ |
617
|
|
|
for (var i in theArray) |
|
|
|
|
618
|
|
|
if (theArray[i] == variable) |
619
|
|
|
return true; |
620
|
|
|
|
621
|
|
|
return false; |
622
|
|
|
} |
623
|
|
|
|
624
|
|
|
// Checks for variable in theArray. |
625
|
|
|
function array_search(variable, theArray) |
626
|
|
|
{ |
627
|
|
|
for (var i in theArray) |
|
|
|
|
628
|
|
|
if (theArray[i] == variable) |
629
|
|
|
return i; |
630
|
|
|
|
631
|
|
|
return null; |
632
|
|
|
} |
633
|
|
|
|
634
|
|
|
// Find a specific radio button in its group and select it. |
635
|
|
|
function selectRadioByName(oRadioGroup, sName) |
636
|
|
|
{ |
637
|
|
|
if (!('length' in oRadioGroup)) |
638
|
|
|
return oRadioGroup.checked = true; |
639
|
|
|
|
640
|
|
|
for (var i = 0, n = oRadioGroup.length; i < n; i++) |
641
|
|
|
if (oRadioGroup[i].value == sName) |
642
|
|
|
return oRadioGroup[i].checked = true; |
643
|
|
|
|
644
|
|
|
return false; |
645
|
|
|
} |
646
|
|
|
|
647
|
|
|
function selectAllRadio(oInvertCheckbox, oForm, sMask, sValue, bIgnoreDisabled) |
648
|
|
|
{ |
649
|
|
|
for (var i = 0; i < oForm.length; i++) |
650
|
|
|
if (oForm[i].name != undefined && oForm[i].name.substr(0, sMask.length) == sMask && oForm[i].value == sValue && (!oForm[i].disabled || (typeof(bIgnoreDisabled) == 'boolean' && bIgnoreDisabled))) |
651
|
|
|
oForm[i].checked = true; |
652
|
|
|
} |
653
|
|
|
|
654
|
|
|
// Invert all checkboxes at once by clicking a single checkbox. |
655
|
|
|
function invertAll(oInvertCheckbox, oForm, sMask, bIgnoreDisabled) |
656
|
|
|
{ |
657
|
|
|
for (var i = 0; i < oForm.length; i++) |
658
|
|
|
{ |
659
|
|
|
if (!('name' in oForm[i]) || (typeof(sMask) == 'string' && oForm[i].name.substr(0, sMask.length) != sMask && oForm[i].id.substr(0, sMask.length) != sMask)) |
660
|
|
|
continue; |
661
|
|
|
|
662
|
|
|
if (!oForm[i].disabled || (typeof(bIgnoreDisabled) == 'boolean' && bIgnoreDisabled)) |
663
|
|
|
oForm[i].checked = oInvertCheckbox.checked; |
664
|
|
|
} |
665
|
|
|
} |
666
|
|
|
|
667
|
|
|
// Keep the session alive - always! |
668
|
|
|
var lastKeepAliveCheck = new Date().getTime(); |
|
|
|
|
669
|
|
|
function smf_sessionKeepAlive() |
670
|
|
|
{ |
671
|
|
|
var curTime = new Date().getTime(); |
672
|
|
|
|
673
|
|
|
// Prevent a Firefox bug from hammering the server. |
674
|
|
|
if (smf_scripturl && curTime - lastKeepAliveCheck > 900000) |
|
|
|
|
675
|
|
|
{ |
676
|
|
|
var tempImage = new Image(); |
677
|
|
|
tempImage.src = smf_prepareScriptUrl(smf_scripturl) + 'action=keepalive;time=' + curTime; |
678
|
|
|
lastKeepAliveCheck = curTime; |
679
|
|
|
} |
680
|
|
|
|
681
|
|
|
window.setTimeout('smf_sessionKeepAlive();', 1200000); |
|
|
|
|
682
|
|
|
} |
683
|
|
|
window.setTimeout('smf_sessionKeepAlive();', 1200000); |
|
|
|
|
684
|
|
|
|
685
|
|
|
// Set a theme option through javascript. |
686
|
|
|
function smf_setThemeOption(theme_var, theme_value, theme_id, theme_cur_session_id, theme_cur_session_var, theme_additional_vars) |
687
|
|
|
{ |
688
|
|
|
// Compatibility. |
689
|
|
|
if (theme_cur_session_id == null) |
690
|
|
|
theme_cur_session_id = smf_session_id; |
691
|
|
|
if (typeof(theme_cur_session_var) == 'undefined') |
692
|
|
|
theme_cur_session_var = 'sesc'; |
693
|
|
|
|
694
|
|
|
if (theme_additional_vars == null) |
695
|
|
|
theme_additional_vars = ''; |
696
|
|
|
|
697
|
|
|
var tempImage = new Image(); |
698
|
|
|
tempImage.src = smf_prepareScriptUrl(smf_scripturl) + 'action=jsoption;var=' + theme_var + ';val=' + theme_value + ';' + theme_cur_session_var + '=' + theme_cur_session_id + theme_additional_vars + (theme_id == null ? '' : '&th=' + theme_id) + ';time=' + (new Date().getTime()); |
699
|
|
|
} |
700
|
|
|
|
701
|
|
|
// Shows the page numbers by clicking the dots (in compact view). |
702
|
|
|
function expandPages(spanNode, baseLink, firstPage, lastPage, perPage) |
703
|
|
|
{ |
704
|
|
|
var replacement = '', i, oldLastPage = 0; |
705
|
|
|
var perPageLimit = 50; |
706
|
|
|
|
707
|
|
|
// Prevent too many pages to be loaded at once. |
708
|
|
|
if ((lastPage - firstPage) / perPage > perPageLimit) |
709
|
|
|
{ |
710
|
|
|
oldLastPage = lastPage; |
711
|
|
|
lastPage = firstPage + perPageLimit * perPage; |
712
|
|
|
} |
713
|
|
|
|
714
|
|
|
// Calculate the new pages. |
715
|
|
|
for (i = firstPage; i < lastPage; i += perPage) |
716
|
|
|
replacement += baseLink.replace(/%1\$d/, i).replace(/%2\$s/, 1 + i / perPage).replace(/%%/g, '%'); |
717
|
|
|
|
718
|
|
|
// Add the new page links. |
719
|
|
|
$(spanNode).before(replacement); |
720
|
|
|
|
721
|
|
|
if (oldLastPage) |
722
|
|
|
// Access the raw DOM element so the native onclick event can be overridden. |
723
|
|
|
spanNode.onclick = function () |
724
|
|
|
{ |
725
|
|
|
expandPages(spanNode, baseLink, lastPage, oldLastPage, perPage); |
726
|
|
|
}; |
727
|
|
|
else |
728
|
|
|
$(spanNode).remove(); |
729
|
|
|
} |
730
|
|
|
|
731
|
|
|
function smc_preCacheImage(sSrc) |
732
|
|
|
{ |
733
|
|
|
if (!('smc_aCachedImages' in window)) |
734
|
|
|
window.smc_aCachedImages = []; |
735
|
|
|
|
736
|
|
|
if (!in_array(sSrc, window.smc_aCachedImages)) |
737
|
|
|
{ |
738
|
|
|
var oImage = new Image(); |
739
|
|
|
oImage.src = sSrc; |
740
|
|
|
} |
741
|
|
|
} |
742
|
|
|
|
743
|
|
|
|
744
|
|
|
// *** smc_Cookie class. |
745
|
|
|
function smc_Cookie(oOptions) |
746
|
|
|
{ |
747
|
|
|
this.opt = oOptions; |
748
|
|
|
this.oCookies = {}; |
749
|
|
|
this.init(); |
750
|
|
|
} |
751
|
|
|
|
752
|
|
|
smc_Cookie.prototype.init = function() |
753
|
|
|
{ |
754
|
|
|
if ('cookie' in document && document.cookie != '') |
755
|
|
|
{ |
756
|
|
|
var aCookieList = document.cookie.split(';'); |
757
|
|
|
for (var i = 0, n = aCookieList.length; i < n; i++) |
758
|
|
|
{ |
759
|
|
|
var aNameValuePair = aCookieList[i].split('='); |
760
|
|
|
this.oCookies[aNameValuePair[0].replace(/^\s+|\s+$/g, '')] = decodeURIComponent(aNameValuePair[1]); |
761
|
|
|
} |
762
|
|
|
} |
763
|
|
|
} |
764
|
|
|
|
765
|
|
|
smc_Cookie.prototype.get = function(sKey) |
766
|
|
|
{ |
767
|
|
|
return sKey in this.oCookies ? this.oCookies[sKey] : null; |
768
|
|
|
} |
769
|
|
|
|
770
|
|
|
smc_Cookie.prototype.set = function(sKey, sValue) |
771
|
|
|
{ |
772
|
|
|
document.cookie = sKey + '=' + encodeURIComponent(sValue); |
773
|
|
|
} |
774
|
|
|
|
775
|
|
|
|
776
|
|
|
// *** smc_Toggle class. |
777
|
|
|
function smc_Toggle(oOptions) |
778
|
|
|
{ |
779
|
|
|
this.opt = oOptions; |
780
|
|
|
this.bCollapsed = false; |
781
|
|
|
this.oCookie = null; |
782
|
|
|
this.init(); |
783
|
|
|
} |
784
|
|
|
|
785
|
|
|
smc_Toggle.prototype.init = function () |
786
|
|
|
{ |
787
|
|
|
// The master switch can disable this toggle fully. |
788
|
|
|
if ('bToggleEnabled' in this.opt && !this.opt.bToggleEnabled) |
789
|
|
|
return; |
790
|
|
|
|
791
|
|
|
// If cookies are enabled and they were set, override the initial state. |
792
|
|
|
if ('oCookieOptions' in this.opt && this.opt.oCookieOptions.bUseCookie) |
793
|
|
|
{ |
794
|
|
|
// Initialize the cookie handler. |
795
|
|
|
this.oCookie = new smc_Cookie({}); |
|
|
|
|
796
|
|
|
|
797
|
|
|
// Check if the cookie is set. |
798
|
|
|
var cookieValue = this.oCookie.get(this.opt.oCookieOptions.sCookieName) |
799
|
|
|
if (cookieValue != null) |
800
|
|
|
this.opt.bCurrentlyCollapsed = cookieValue == '1'; |
801
|
|
|
} |
802
|
|
|
|
803
|
|
|
// Initialize the images to be clickable. |
804
|
|
|
if ('aSwapImages' in this.opt) |
805
|
|
|
{ |
806
|
|
|
for (var i = 0, n = this.opt.aSwapImages.length; i < n; i++) |
807
|
|
|
{ |
808
|
|
|
this.opt.aSwapImages[i].isCSS = (typeof this.opt.aSwapImages[i].srcCollapsed == 'undefined'); |
809
|
|
|
if (this.opt.aSwapImages[i].isCSS) |
810
|
|
|
{ |
811
|
|
|
if (!this.opt.aSwapImages[i].cssCollapsed) |
812
|
|
|
this.opt.aSwapImages[i].cssCollapsed = 'toggle_down'; |
813
|
|
|
if (!this.opt.aSwapImages[i].cssExpanded) |
814
|
|
|
this.opt.aSwapImages[i].cssExpanded = 'toggle_up'; |
815
|
|
|
} |
816
|
|
|
else |
817
|
|
|
{ |
818
|
|
|
// Preload the collapsed image. |
819
|
|
|
smc_preCacheImage(this.opt.aSwapImages[i].srcCollapsed); |
820
|
|
|
} |
821
|
|
|
|
822
|
|
|
// Display the image in case it was hidden. |
823
|
|
|
$('#' + this.opt.aSwapImages[i].sId).show(); |
824
|
|
|
var oImage = document.getElementById(this.opt.aSwapImages[i].sId); |
825
|
|
|
if (typeof(oImage) == 'object' && oImage != null) |
826
|
|
|
{ |
827
|
|
|
oImage.instanceRef = this; |
828
|
|
|
oImage.onclick = function () { |
829
|
|
|
this.instanceRef.toggle(); |
830
|
|
|
this.blur(); |
831
|
|
|
} |
832
|
|
|
oImage.style.cursor = 'pointer'; |
833
|
|
|
} |
834
|
|
|
} |
835
|
|
|
} |
836
|
|
|
|
837
|
|
|
// Initialize links. |
838
|
|
|
if ('aSwapLinks' in this.opt) |
839
|
|
|
{ |
840
|
|
|
for (var i = 0, n = this.opt.aSwapLinks.length; i < n; i++) |
|
|
|
|
841
|
|
|
{ |
842
|
|
|
var oLink = document.getElementById(this.opt.aSwapLinks[i].sId); |
843
|
|
|
if (typeof(oLink) == 'object' && oLink != null) |
844
|
|
|
{ |
845
|
|
|
// Display the link in case it was hidden. |
846
|
|
|
if (oLink.style.display == 'none') |
847
|
|
|
oLink.style.display = ''; |
848
|
|
|
|
849
|
|
|
oLink.instanceRef = this; |
850
|
|
|
oLink.onclick = function () { |
851
|
|
|
this.instanceRef.toggle(); |
852
|
|
|
this.blur(); |
853
|
|
|
return false; |
854
|
|
|
} |
855
|
|
|
} |
856
|
|
|
} |
857
|
|
|
} |
858
|
|
|
|
859
|
|
|
// If the init state is set to be collapsed, collapse it. |
860
|
|
|
if (this.opt.bCurrentlyCollapsed) |
861
|
|
|
this.changeState(true, true); |
862
|
|
|
} |
863
|
|
|
|
864
|
|
|
// Collapse or expand the section. |
865
|
|
|
smc_Toggle.prototype.changeState = function(bCollapse, bInit) |
866
|
|
|
{ |
867
|
|
|
// Default bInit to false. |
868
|
|
|
bInit = typeof(bInit) == 'undefined' ? false : true; |
869
|
|
|
|
870
|
|
|
// Handle custom function hook before collapse. |
871
|
|
|
if (!bInit && bCollapse && 'funcOnBeforeCollapse' in this.opt) |
872
|
|
|
{ |
873
|
|
|
this.tmpMethod = this.opt.funcOnBeforeCollapse; |
874
|
|
|
this.tmpMethod(); |
875
|
|
|
delete this.tmpMethod; |
876
|
|
|
} |
877
|
|
|
|
878
|
|
|
// Handle custom function hook before expand. |
879
|
|
|
else if (!bInit && !bCollapse && 'funcOnBeforeExpand' in this.opt) |
880
|
|
|
{ |
881
|
|
|
this.tmpMethod = this.opt.funcOnBeforeExpand; |
882
|
|
|
this.tmpMethod(); |
883
|
|
|
delete this.tmpMethod; |
884
|
|
|
} |
885
|
|
|
|
886
|
|
|
// Loop through all the images that need to be toggled. |
887
|
|
|
if ('aSwapImages' in this.opt) |
888
|
|
|
{ |
889
|
|
|
for (var i = 0, n = this.opt.aSwapImages.length; i < n; i++) |
890
|
|
|
{ |
891
|
|
|
if (this.opt.aSwapImages[i].isCSS) |
892
|
|
|
{ |
893
|
|
|
$('#' + this.opt.aSwapImages[i].sId).toggleClass(this.opt.aSwapImages[i].cssCollapsed, bCollapse).toggleClass(this.opt.aSwapImages[i].cssExpanded, !bCollapse).attr('title', bCollapse ? this.opt.aSwapImages[i].altCollapsed : this.opt.aSwapImages[i].altExpanded); |
894
|
|
|
} |
895
|
|
|
else |
896
|
|
|
{ |
897
|
|
|
var oImage = document.getElementById(this.opt.aSwapImages[i].sId); |
898
|
|
|
if (typeof(oImage) == 'object' && oImage != null) |
899
|
|
|
{ |
900
|
|
|
// Only (re)load the image if it's changed. |
901
|
|
|
var sTargetSource = bCollapse ? this.opt.aSwapImages[i].srcCollapsed : this.opt.aSwapImages[i].srcExpanded; |
902
|
|
|
if (oImage.src != sTargetSource) |
903
|
|
|
oImage.src = sTargetSource; |
904
|
|
|
|
905
|
|
|
oImage.alt = oImage.title = bCollapse ? this.opt.aSwapImages[i].altCollapsed : this.opt.aSwapImages[i].altExpanded; |
906
|
|
|
} |
907
|
|
|
} |
908
|
|
|
} |
909
|
|
|
} |
910
|
|
|
|
911
|
|
|
// Loop through all the links that need to be toggled. |
912
|
|
|
if ('aSwapLinks' in this.opt) |
913
|
|
|
{ |
914
|
|
|
for (var i = 0, n = this.opt.aSwapLinks.length; i < n; i++) |
|
|
|
|
915
|
|
|
{ |
916
|
|
|
var oLink = document.getElementById(this.opt.aSwapLinks[i].sId); |
917
|
|
|
if (typeof(oLink) == 'object' && oLink != null) |
918
|
|
|
setInnerHTML(oLink, bCollapse ? this.opt.aSwapLinks[i].msgCollapsed : this.opt.aSwapLinks[i].msgExpanded); |
919
|
|
|
} |
920
|
|
|
} |
921
|
|
|
|
922
|
|
|
// Now go through all the sections to be collapsed. |
923
|
|
|
for (var i = 0, n = this.opt.aSwappableContainers.length; i < n; i++) |
|
|
|
|
924
|
|
|
{ |
925
|
|
|
if (this.opt.aSwappableContainers[i] == null) |
926
|
|
|
continue; |
927
|
|
|
|
928
|
|
|
var oContainer = document.getElementById(this.opt.aSwappableContainers[i]); |
929
|
|
|
if (typeof(oContainer) == 'object' && oContainer != null) |
930
|
|
|
{ |
931
|
|
|
if (!!this.opt.bNoAnimate || bInit) |
932
|
|
|
{ |
933
|
|
|
$(oContainer).toggle(!bCollapse); |
934
|
|
|
} |
935
|
|
|
else |
936
|
|
|
{ |
937
|
|
|
if (bCollapse) |
938
|
|
|
{ |
939
|
|
|
if (this.opt.aHeader != null && this.opt.aHeader.hasClass('cat_bar')) |
940
|
|
|
$(this.opt.aHeader).addClass('collapsed'); |
941
|
|
|
$(oContainer).slideUp(); |
942
|
|
|
} |
943
|
|
|
else |
944
|
|
|
{ |
945
|
|
|
if (this.opt.aHeader != null && this.opt.aHeader.hasClass('cat_bar')) |
946
|
|
|
$(this.opt.aHeader).removeClass('collapsed'); |
947
|
|
|
$(oContainer).slideDown(); |
948
|
|
|
} |
949
|
|
|
} |
950
|
|
|
} |
951
|
|
|
} |
952
|
|
|
|
953
|
|
|
// Update the new state. |
954
|
|
|
this.bCollapsed = bCollapse; |
955
|
|
|
|
956
|
|
|
// Update the cookie, if desired. |
957
|
|
|
if ('oCookieOptions' in this.opt && this.opt.oCookieOptions.bUseCookie) |
958
|
|
|
this.oCookie.set(this.opt.oCookieOptions.sCookieName, this.bCollapsed | 0); |
959
|
|
|
|
960
|
|
|
if (!bInit && 'oThemeOptions' in this.opt && this.opt.oThemeOptions.bUseThemeSettings) |
961
|
|
|
smf_setThemeOption(this.opt.oThemeOptions.sOptionName, this.bCollapsed | 0, 'sThemeId' in this.opt.oThemeOptions ? this.opt.oThemeOptions.sThemeId : null, smf_session_id, smf_session_var, 'sAdditionalVars' in this.opt.oThemeOptions ? this.opt.oThemeOptions.sAdditionalVars : null); |
962
|
|
|
} |
963
|
|
|
|
964
|
|
|
smc_Toggle.prototype.toggle = function() |
965
|
|
|
{ |
966
|
|
|
// Change the state by reversing the current state. |
967
|
|
|
this.changeState(!this.bCollapsed); |
968
|
|
|
} |
969
|
|
|
|
970
|
|
|
|
971
|
|
|
function ajax_indicator(turn_on) |
972
|
|
|
{ |
973
|
|
|
if (ajax_indicator_ele == null) |
974
|
|
|
{ |
975
|
|
|
ajax_indicator_ele = document.getElementById('ajax_in_progress'); |
976
|
|
|
|
977
|
|
|
if (ajax_indicator_ele == null && typeof(ajax_notification_text) != null) |
978
|
|
|
{ |
979
|
|
|
create_ajax_indicator_ele(); |
980
|
|
|
} |
981
|
|
|
} |
982
|
|
|
|
983
|
|
|
if (ajax_indicator_ele != null) |
984
|
|
|
{ |
985
|
|
|
ajax_indicator_ele.style.display = turn_on ? 'block' : 'none'; |
986
|
|
|
} |
987
|
|
|
} |
988
|
|
|
|
989
|
|
|
function create_ajax_indicator_ele() |
990
|
|
|
{ |
991
|
|
|
// Create the div for the indicator. |
992
|
|
|
ajax_indicator_ele = document.createElement('div'); |
993
|
|
|
|
994
|
|
|
// Set the id so it'll load the style properly. |
995
|
|
|
ajax_indicator_ele.id = 'ajax_in_progress'; |
996
|
|
|
|
997
|
|
|
// Set the text. (Note: You MUST append here and not overwrite.) |
998
|
|
|
ajax_indicator_ele.innerHTML += ajax_notification_text; |
999
|
|
|
|
1000
|
|
|
// Finally attach the element to the body. |
1001
|
|
|
document.body.appendChild(ajax_indicator_ele); |
1002
|
|
|
} |
1003
|
|
|
|
1004
|
|
|
function createEventListener(oTarget) |
1005
|
|
|
{ |
1006
|
|
|
if (!('addEventListener' in oTarget)) |
1007
|
|
|
{ |
1008
|
|
|
if (oTarget.attachEvent) |
1009
|
|
|
{ |
1010
|
|
|
oTarget.addEventListener = function (sEvent, funcHandler, bCapture) { |
|
|
|
|
1011
|
|
|
oTarget.attachEvent('on' + sEvent, funcHandler); |
1012
|
|
|
} |
1013
|
|
|
oTarget.removeEventListener = function (sEvent, funcHandler, bCapture) { |
|
|
|
|
1014
|
|
|
oTarget.detachEvent('on' + sEvent, funcHandler); |
1015
|
|
|
} |
1016
|
|
|
} |
1017
|
|
|
else |
1018
|
|
|
{ |
1019
|
|
|
oTarget.addEventListener = function (sEvent, funcHandler, bCapture) { |
|
|
|
|
1020
|
|
|
oTarget['on' + sEvent] = funcHandler; |
1021
|
|
|
} |
1022
|
|
|
oTarget.removeEventListener = function (sEvent, funcHandler, bCapture) { |
|
|
|
|
1023
|
|
|
oTarget['on' + sEvent] = null; |
1024
|
|
|
} |
1025
|
|
|
} |
1026
|
|
|
} |
1027
|
|
|
} |
1028
|
|
|
|
1029
|
|
|
// This function will retrieve the contents needed for the jump to boxes. |
1030
|
|
|
function grabJumpToContent(elem) |
|
|
|
|
1031
|
|
|
{ |
1032
|
|
|
var oXMLDoc = getXMLDocument(smf_prepareScriptUrl(smf_scripturl) + 'action=xmlhttp;sa=jumpto;xml'); |
1033
|
|
|
var aBoardsAndCategories = []; |
1034
|
|
|
|
1035
|
|
|
ajax_indicator(true); |
1036
|
|
|
|
1037
|
|
|
oXMLDoc.done(function(data, textStatus, jqXHR){ |
|
|
|
|
1038
|
|
|
|
1039
|
|
|
var items = $(data).find('item'); |
1040
|
|
|
items.each(function(i) { |
1041
|
|
|
aBoardsAndCategories[i] = { |
1042
|
|
|
id: parseInt($(this).attr('id')), |
1043
|
|
|
isCategory: $(this).attr('type') == 'category', |
1044
|
|
|
name: this.firstChild.nodeValue.removeEntities(), |
1045
|
|
|
is_current: false, |
1046
|
|
|
childLevel: parseInt($(this).attr('childlevel')) |
1047
|
|
|
} |
1048
|
|
|
}); |
1049
|
|
|
|
1050
|
|
|
ajax_indicator(false); |
1051
|
|
|
|
1052
|
|
|
for (var i = 0, n = aJumpTo.length; i < n; i++) |
1053
|
|
|
{ |
1054
|
|
|
aJumpTo[i].fillSelect(aBoardsAndCategories); |
1055
|
|
|
} |
1056
|
|
|
}); |
1057
|
|
|
} |
1058
|
|
|
|
1059
|
|
|
// This'll contain all JumpTo objects on the page. |
1060
|
|
|
var aJumpTo = new Array(); |
1061
|
|
|
|
1062
|
|
|
// *** JumpTo class. |
1063
|
|
|
function JumpTo(oJumpToOptions) |
1064
|
|
|
{ |
1065
|
|
|
this.opt = oJumpToOptions; |
1066
|
|
|
this.dropdownList = null; |
1067
|
|
|
this.showSelect(); |
1068
|
|
|
|
1069
|
|
|
// Register a change event after the select has been created. |
1070
|
|
|
$('#' + this.opt.sContainerId).one('mouseenter', function() { |
1071
|
|
|
grabJumpToContent(this); |
1072
|
|
|
}); |
1073
|
|
|
} |
1074
|
|
|
|
1075
|
|
|
// Show the initial select box (onload). Method of the JumpTo class. |
1076
|
|
|
JumpTo.prototype.showSelect = function () |
1077
|
|
|
{ |
1078
|
|
|
var sChildLevelPrefix = ''; |
1079
|
|
|
for (var i = this.opt.iCurBoardChildLevel; i > 0; i--) |
1080
|
|
|
sChildLevelPrefix += this.opt.sBoardChildLevelIndicator; |
1081
|
|
|
setInnerHTML(document.getElementById(this.opt.sContainerId), this.opt.sJumpToTemplate.replace(/%select_id%/, this.opt.sContainerId + '_select').replace(/%dropdown_list%/, '<select ' + (this.opt.bDisabled == true ? 'disabled ' : '') + (this.opt.sClassName != undefined ? 'class="' + this.opt.sClassName + '" ' : '') + 'name="' + (this.opt.sCustomName != undefined ? this.opt.sCustomName : this.opt.sContainerId + '_select') + '" id="' + this.opt.sContainerId + '_select"><option value="' + (this.opt.bNoRedirect != undefined && this.opt.bNoRedirect == true ? this.opt.iCurBoardId : '?board=' + this.opt.iCurBoardId + '.0') + '">' + sChildLevelPrefix + this.opt.sBoardPrefix + this.opt.sCurBoardName.removeEntities() + '</option></select> ' + (this.opt.sGoButtonLabel != undefined ? '<input type="button" class="button" value="' + this.opt.sGoButtonLabel + '" onclick="window.location.href = \'' + smf_prepareScriptUrl(smf_scripturl) + 'board=' + this.opt.iCurBoardId + '.0\';">' : ''))); |
1082
|
|
|
this.dropdownList = document.getElementById(this.opt.sContainerId + '_select'); |
1083
|
|
|
} |
1084
|
|
|
|
1085
|
|
|
// Fill the jump to box with entries. Method of the JumpTo class. |
1086
|
|
|
JumpTo.prototype.fillSelect = function (aBoardsAndCategories) |
1087
|
|
|
{ |
1088
|
|
|
var iIndexPointer = 0; |
|
|
|
|
1089
|
|
|
|
1090
|
|
|
// Create an option that'll be above and below the category. |
1091
|
|
|
var oDashOption = document.createElement('option'); |
1092
|
|
|
oDashOption.appendChild(document.createTextNode(this.opt.sCatSeparator)); |
1093
|
|
|
oDashOption.disabled = 'disabled'; |
1094
|
|
|
oDashOption.value = ''; |
1095
|
|
|
|
1096
|
|
|
if ('onbeforeactivate' in document) |
1097
|
|
|
this.dropdownList.onbeforeactivate = null; |
1098
|
|
|
else |
1099
|
|
|
this.dropdownList.onfocus = null; |
1100
|
|
|
|
1101
|
|
|
if (this.opt.bNoRedirect) |
1102
|
|
|
this.dropdownList.options[0].disabled = 'disabled'; |
1103
|
|
|
|
1104
|
|
|
// Create a document fragment that'll allowing inserting big parts at once. |
1105
|
|
|
var oListFragment = document.createDocumentFragment(); |
1106
|
|
|
|
1107
|
|
|
// Loop through all items to be added. |
1108
|
|
|
for (var i = 0, n = aBoardsAndCategories.length; i < n; i++) |
1109
|
|
|
{ |
1110
|
|
|
var j, sChildLevelPrefix, oOption; |
1111
|
|
|
|
1112
|
|
|
// If we've reached the currently selected board add all items so far. |
1113
|
|
|
if (!aBoardsAndCategories[i].isCategory && aBoardsAndCategories[i].id == this.opt.iCurBoardId) |
1114
|
|
|
{ |
1115
|
|
|
this.dropdownList.insertBefore(oListFragment, this.dropdownList.options[0]); |
1116
|
|
|
oListFragment = document.createDocumentFragment(); |
1117
|
|
|
continue; |
1118
|
|
|
} |
1119
|
|
|
|
1120
|
|
|
if (aBoardsAndCategories[i].isCategory) |
1121
|
|
|
oListFragment.appendChild(oDashOption.cloneNode(true)); |
1122
|
|
|
else |
1123
|
|
|
for (j = aBoardsAndCategories[i].childLevel, sChildLevelPrefix = ''; j > 0; j--) |
1124
|
|
|
sChildLevelPrefix += this.opt.sBoardChildLevelIndicator; |
1125
|
|
|
|
1126
|
|
|
oOption = document.createElement('option'); |
1127
|
|
|
oOption.appendChild(document.createTextNode((aBoardsAndCategories[i].isCategory ? this.opt.sCatPrefix : sChildLevelPrefix + this.opt.sBoardPrefix) + aBoardsAndCategories[i].name)); |
|
|
|
|
1128
|
|
|
if (!this.opt.bNoRedirect) |
1129
|
|
|
oOption.value = aBoardsAndCategories[i].isCategory ? '#c' + aBoardsAndCategories[i].id : '?board=' + aBoardsAndCategories[i].id + '.0'; |
1130
|
|
|
else |
1131
|
|
|
{ |
1132
|
|
|
if (aBoardsAndCategories[i].isCategory) |
1133
|
|
|
oOption.disabled = 'disabled'; |
1134
|
|
|
else |
1135
|
|
|
oOption.value = aBoardsAndCategories[i].id; |
1136
|
|
|
} |
1137
|
|
|
oListFragment.appendChild(oOption); |
1138
|
|
|
|
1139
|
|
|
if (aBoardsAndCategories[i].isCategory) |
1140
|
|
|
oListFragment.appendChild(oDashOption.cloneNode(true)); |
1141
|
|
|
} |
1142
|
|
|
|
1143
|
|
|
// Add the remaining items after the currently selected item. |
1144
|
|
|
this.dropdownList.appendChild(oListFragment); |
1145
|
|
|
|
1146
|
|
|
// Add an onchange action |
1147
|
|
|
if (!this.opt.bNoRedirect) |
1148
|
|
|
this.dropdownList.onchange = function() { |
1149
|
|
|
if (this.selectedIndex > 0 && this.options[this.selectedIndex].value) |
1150
|
|
|
window.location.href = smf_scripturl + this.options[this.selectedIndex].value.substr(smf_scripturl.indexOf('?') == -1 || this.options[this.selectedIndex].value.substr(0, 1) != '?' ? 0 : 1); |
1151
|
|
|
} |
1152
|
|
|
} |
1153
|
|
|
|
1154
|
|
|
// A global array containing all IconList objects. |
1155
|
|
|
var aIconLists = new Array(); |
1156
|
|
|
|
1157
|
|
|
// *** IconList object. |
1158
|
|
|
function IconList(oOptions) |
1159
|
|
|
{ |
1160
|
|
|
if (!window.XMLHttpRequest) |
1161
|
|
|
return; |
1162
|
|
|
|
1163
|
|
|
this.opt = oOptions; |
1164
|
|
|
this.bListLoaded = false; |
1165
|
|
|
this.oContainerDiv = null; |
1166
|
|
|
this.funcMousedownHandler = null; |
1167
|
|
|
this.funcParent = this; |
1168
|
|
|
this.iCurMessageId = 0; |
1169
|
|
|
this.iCurTimeout = 0; |
1170
|
|
|
|
1171
|
|
|
// Add backwards compatibility with old themes. |
1172
|
|
|
if (!('sSessionVar' in this.opt)) |
1173
|
|
|
this.opt.sSessionVar = 'sesc'; |
1174
|
|
|
|
1175
|
|
|
this.initIcons(); |
1176
|
|
|
} |
1177
|
|
|
|
1178
|
|
|
// Replace all message icons by icons with hoverable and clickable div's. |
1179
|
|
|
IconList.prototype.initIcons = function () |
1180
|
|
|
{ |
1181
|
|
|
for (var i = document.images.length - 1, iPrefixLength = this.opt.sIconIdPrefix.length; i >= 0; i--) |
1182
|
|
|
if (document.images[i].id.substr(0, iPrefixLength) == this.opt.sIconIdPrefix) |
1183
|
|
|
setOuterHTML(document.images[i], '<div title="' + this.opt.sLabelIconList + '" onclick="' + this.opt.sBackReference + '.openPopup(this, ' + document.images[i].id.substr(iPrefixLength) + ')" onmouseover="' + this.opt.sBackReference + '.onBoxHover(this, true)" onmouseout="' + this.opt.sBackReference + '.onBoxHover(this, false)" style="background: ' + this.opt.sBoxBackground + '; cursor: pointer; padding: 3px; text-align: center;"><img src="' + document.images[i].src + '" alt="' + document.images[i].alt + '" id="' + document.images[i].id + '"></div>'); |
1184
|
|
|
} |
1185
|
|
|
|
1186
|
|
|
// Event for the mouse hovering over the original icon. |
1187
|
|
|
IconList.prototype.onBoxHover = function (oDiv, bMouseOver) |
1188
|
|
|
{ |
1189
|
|
|
oDiv.style.border = bMouseOver ? this.opt.iBoxBorderWidthHover + 'px solid ' + this.opt.sBoxBorderColorHover : ''; |
1190
|
|
|
oDiv.style.background = bMouseOver ? this.opt.sBoxBackgroundHover : this.opt.sBoxBackground; |
1191
|
|
|
oDiv.style.padding = bMouseOver ? (3 - this.opt.iBoxBorderWidthHover) + 'px' : '3px' |
1192
|
|
|
} |
1193
|
|
|
|
1194
|
|
|
// Show the list of icons after the user clicked the original icon. |
1195
|
|
|
IconList.prototype.openPopup = function (oDiv, iMessageId) |
1196
|
|
|
{ |
1197
|
|
|
this.iCurMessageId = iMessageId; |
1198
|
|
|
|
1199
|
|
|
if (!this.bListLoaded && this.oContainerDiv == null) |
1200
|
|
|
{ |
1201
|
|
|
// Create a container div. |
1202
|
|
|
this.oContainerDiv = document.createElement('div'); |
1203
|
|
|
this.oContainerDiv.id = 'iconList'; |
1204
|
|
|
this.oContainerDiv.style.display = 'none'; |
1205
|
|
|
this.oContainerDiv.style.cursor = 'pointer'; |
1206
|
|
|
this.oContainerDiv.style.position = 'absolute'; |
1207
|
|
|
this.oContainerDiv.style.background = this.opt.sContainerBackground; |
1208
|
|
|
this.oContainerDiv.style.border = this.opt.sContainerBorder; |
1209
|
|
|
this.oContainerDiv.style.padding = '6px 0px'; |
1210
|
|
|
document.body.appendChild(this.oContainerDiv); |
1211
|
|
|
|
1212
|
|
|
// Start to fetch its contents. |
1213
|
|
|
ajax_indicator(true); |
1214
|
|
|
sendXMLDocument.call(this, smf_prepareScriptUrl(smf_scripturl) + 'action=xmlhttp;sa=messageicons;board=' + this.opt.iBoardId + ';xml', '', this.onIconsReceived); |
1215
|
|
|
|
1216
|
|
|
createEventListener(document.body); |
1217
|
|
|
} |
1218
|
|
|
|
1219
|
|
|
// Set the position of the container. |
1220
|
|
|
var aPos = smf_itemPos(oDiv); |
1221
|
|
|
|
1222
|
|
|
this.oContainerDiv.style.top = (aPos[1] + oDiv.offsetHeight) + 'px'; |
1223
|
|
|
this.oContainerDiv.style.left = (aPos[0] - 1) + 'px'; |
1224
|
|
|
this.oClickedIcon = oDiv; |
1225
|
|
|
|
1226
|
|
|
if (this.bListLoaded) |
1227
|
|
|
this.oContainerDiv.style.display = 'block'; |
1228
|
|
|
|
1229
|
|
|
document.body.addEventListener('mousedown', this.onWindowMouseDown, false); |
1230
|
|
|
} |
1231
|
|
|
|
1232
|
|
|
// Setup the list of icons once it is received through xmlHTTP. |
1233
|
|
|
IconList.prototype.onIconsReceived = function (oXMLDoc) |
1234
|
|
|
{ |
1235
|
|
|
var icons = oXMLDoc.getElementsByTagName('smf')[0].getElementsByTagName('icon'); |
1236
|
|
|
var sItems = ''; |
1237
|
|
|
|
1238
|
|
|
for (var i = 0, n = icons.length; i < n; i++) |
1239
|
|
|
sItems += '<span onmouseover="' + this.opt.sBackReference + '.onItemHover(this, true)" onmouseout="' + this.opt.sBackReference + '.onItemHover(this, false);" onmousedown="' + this.opt.sBackReference + '.onItemMouseDown(this, \'' + icons[i].getAttribute('value') + '\');" style="padding: 2px 3px; line-height: 20px; border: ' + this.opt.sItemBorder + '; background: ' + this.opt.sItemBackground + '"><img src="' + icons[i].getAttribute('url') + '" alt="' + icons[i].getAttribute('name') + '" title="' + icons[i].firstChild.nodeValue + '" style="vertical-align: middle"></span>'; |
1240
|
|
|
|
1241
|
|
|
setInnerHTML(this.oContainerDiv, sItems); |
1242
|
|
|
this.oContainerDiv.style.display = 'block'; |
1243
|
|
|
this.bListLoaded = true; |
1244
|
|
|
|
1245
|
|
|
if (is_ie) |
1246
|
|
|
this.oContainerDiv.style.width = this.oContainerDiv.clientWidth + 'px'; |
1247
|
|
|
|
1248
|
|
|
ajax_indicator(false); |
1249
|
|
|
} |
1250
|
|
|
|
1251
|
|
|
// Event handler for hovering over the icons. |
1252
|
|
|
IconList.prototype.onItemHover = function (oDiv, bMouseOver) |
1253
|
|
|
{ |
1254
|
|
|
oDiv.style.background = bMouseOver ? this.opt.sItemBackgroundHover : this.opt.sItemBackground; |
1255
|
|
|
oDiv.style.border = bMouseOver ? this.opt.sItemBorderHover : this.opt.sItemBorder; |
1256
|
|
|
if (this.iCurTimeout != 0) |
1257
|
|
|
window.clearTimeout(this.iCurTimeout); |
1258
|
|
|
if (bMouseOver) |
1259
|
|
|
this.onBoxHover(this.oClickedIcon, true); |
1260
|
|
|
else |
1261
|
|
|
this.iCurTimeout = window.setTimeout(this.opt.sBackReference + '.collapseList();', 500); |
1262
|
|
|
} |
1263
|
|
|
|
1264
|
|
|
// Event handler for clicking on one of the icons. |
1265
|
|
|
IconList.prototype.onItemMouseDown = function (oDiv, sNewIcon) |
1266
|
|
|
{ |
1267
|
|
|
if (this.iCurMessageId != 0) |
1268
|
|
|
{ |
1269
|
|
|
ajax_indicator(true); |
1270
|
|
|
this.tmpMethod = getXMLDocument; |
1271
|
|
|
var oXMLDoc = this.tmpMethod(smf_prepareScriptUrl(smf_scripturl) + 'action=jsmodify;topic=' + this.opt.iTopicId + ';msg=' + this.iCurMessageId + ';' + smf_session_var + '=' + smf_session_id + ';icon=' + sNewIcon + ';xml'), |
1272
|
|
|
oThis = this; |
1273
|
|
|
delete this.tmpMethod; |
1274
|
|
|
ajax_indicator(false); |
1275
|
|
|
|
1276
|
|
|
oXMLDoc.done(function(data, textStatus, jqXHR){ |
|
|
|
|
1277
|
|
|
oMessage = $(data).find('message') |
|
|
|
|
1278
|
|
|
curMessageId = oMessage.attr('id').replace( /^\D+/g, ''); |
|
|
|
|
1279
|
|
|
|
1280
|
|
|
if (oMessage.find('error').length == 0) |
1281
|
|
|
{ |
1282
|
|
|
if (oThis.opt.bShowModify && oMessage.find('modified').length != 0) |
1283
|
|
|
$('#modified_' + curMessageId).html(oMessage.find('modified').text()); |
1284
|
|
|
|
1285
|
|
|
oThis.oClickedIcon.getElementsByTagName('img')[0].src = oDiv.getElementsByTagName('img')[0].src; |
1286
|
|
|
} |
1287
|
|
|
}); |
1288
|
|
|
} |
1289
|
|
|
} |
1290
|
|
|
|
1291
|
|
|
// Event handler for clicking outside the list (will make the list disappear). |
1292
|
|
|
IconList.prototype.onWindowMouseDown = function () |
1293
|
|
|
{ |
1294
|
|
|
for (var i = aIconLists.length - 1; i >= 0; i--) |
1295
|
|
|
{ |
1296
|
|
|
aIconLists[i].funcParent.tmpMethod = aIconLists[i].collapseList; |
1297
|
|
|
aIconLists[i].funcParent.tmpMethod(); |
1298
|
|
|
delete aIconLists[i].funcParent.tmpMethod; |
1299
|
|
|
} |
1300
|
|
|
} |
1301
|
|
|
|
1302
|
|
|
// Collapse the list of icons. |
1303
|
|
|
IconList.prototype.collapseList = function() |
1304
|
|
|
{ |
1305
|
|
|
this.onBoxHover(this.oClickedIcon, false); |
1306
|
|
|
this.oContainerDiv.style.display = 'none'; |
1307
|
|
|
this.iCurMessageId = 0; |
1308
|
|
|
document.body.removeEventListener('mousedown', this.onWindowMouseDown, false); |
1309
|
|
|
} |
1310
|
|
|
|
1311
|
|
|
// Handy shortcuts for getting the mouse position on the screen - only used for IE at the moment. |
1312
|
|
|
function smf_mousePose(oEvent) |
1313
|
|
|
{ |
1314
|
|
|
var x = 0; |
1315
|
|
|
var y = 0; |
1316
|
|
|
|
1317
|
|
|
if (oEvent.pageX) |
1318
|
|
|
{ |
1319
|
|
|
y = oEvent.pageY; |
1320
|
|
|
x = oEvent.pageX; |
1321
|
|
|
} |
1322
|
|
|
else if (oEvent.clientX) |
1323
|
|
|
{ |
1324
|
|
|
x = oEvent.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft); |
1325
|
|
|
y = oEvent.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop); |
1326
|
|
|
} |
1327
|
|
|
|
1328
|
|
|
return [x, y]; |
1329
|
|
|
} |
1330
|
|
|
|
1331
|
|
|
// Short function for finding the actual position of an item. |
1332
|
|
|
function smf_itemPos(itemHandle) |
1333
|
|
|
{ |
1334
|
|
|
var itemX = 0; |
1335
|
|
|
var itemY = 0; |
1336
|
|
|
|
1337
|
|
|
if ('offsetParent' in itemHandle) |
1338
|
|
|
{ |
1339
|
|
|
itemX = itemHandle.offsetLeft; |
1340
|
|
|
itemY = itemHandle.offsetTop; |
1341
|
|
|
while (itemHandle.offsetParent && typeof(itemHandle.offsetParent) == 'object') |
1342
|
|
|
{ |
1343
|
|
|
itemHandle = itemHandle.offsetParent; |
1344
|
|
|
itemX += itemHandle.offsetLeft; |
1345
|
|
|
itemY += itemHandle.offsetTop; |
1346
|
|
|
} |
1347
|
|
|
} |
1348
|
|
|
else if ('x' in itemHandle) |
1349
|
|
|
{ |
1350
|
|
|
itemX = itemHandle.x; |
1351
|
|
|
itemY = itemHandle.y; |
1352
|
|
|
} |
1353
|
|
|
|
1354
|
|
|
return [itemX, itemY]; |
1355
|
|
|
} |
1356
|
|
|
|
1357
|
|
|
// This function takes the script URL and prepares it to allow the query string to be appended to it. |
1358
|
|
|
function smf_prepareScriptUrl(sUrl) |
1359
|
|
|
{ |
1360
|
|
|
return sUrl.indexOf('?') == -1 ? sUrl + '?' : sUrl + (sUrl.charAt(sUrl.length - 1) == '?' || sUrl.charAt(sUrl.length - 1) == '&' || sUrl.charAt(sUrl.length - 1) == ';' ? '' : ';'); |
1361
|
|
|
} |
1362
|
|
|
|
1363
|
|
|
var aOnloadEvents = new Array(); |
1364
|
|
|
function addLoadEvent(fNewOnload) |
1365
|
|
|
{ |
1366
|
|
|
// If there's no event set, just set this one |
1367
|
|
|
if (typeof(fNewOnload) == 'function' && (!('onload' in window) || typeof(window.onload) != 'function')) |
1368
|
|
|
window.onload = fNewOnload; |
1369
|
|
|
|
1370
|
|
|
// If there's just one event, setup the array. |
1371
|
|
|
else if (aOnloadEvents.length == 0) |
1372
|
|
|
{ |
1373
|
|
|
aOnloadEvents[0] = window.onload; |
1374
|
|
|
aOnloadEvents[1] = fNewOnload; |
1375
|
|
|
window.onload = function() { |
1376
|
|
|
for (var i = 0, n = aOnloadEvents.length; i < n; i++) |
1377
|
|
|
{ |
1378
|
|
|
if (typeof(aOnloadEvents[i]) == 'function') |
1379
|
|
|
aOnloadEvents[i](); |
1380
|
|
|
else if (typeof(aOnloadEvents[i]) == 'string') |
1381
|
|
|
eval(aOnloadEvents[i]); |
|
|
|
|
1382
|
|
|
} |
1383
|
|
|
} |
1384
|
|
|
} |
1385
|
|
|
|
1386
|
|
|
// This isn't the first event function, add it to the list. |
1387
|
|
|
else |
1388
|
|
|
aOnloadEvents[aOnloadEvents.length] = fNewOnload; |
1389
|
|
|
} |
1390
|
|
|
|
1391
|
|
|
// Get the text in a code tag. |
1392
|
|
|
function smfSelectText(oCurElement, bActOnElement) |
1393
|
|
|
{ |
1394
|
|
|
// The place we're looking for is one div up, and next door - if it's auto detect. |
1395
|
|
|
if (typeof(bActOnElement) == 'boolean' && bActOnElement) |
1396
|
|
|
var oCodeArea = document.getElementById(oCurElement); |
1397
|
|
|
else |
1398
|
|
|
var oCodeArea = oCurElement.parentNode.nextSibling; |
|
|
|
|
1399
|
|
|
|
1400
|
|
|
if (typeof(oCodeArea) != 'object' || oCodeArea == null) |
1401
|
|
|
return false; |
1402
|
|
|
|
1403
|
|
|
// Start off with my favourite, internet explorer. |
1404
|
|
|
if ('createTextRange' in document.body) |
1405
|
|
|
{ |
1406
|
|
|
var oCurRange = document.body.createTextRange(); |
1407
|
|
|
oCurRange.moveToElementText(oCodeArea); |
1408
|
|
|
oCurRange.select(); |
1409
|
|
|
} |
1410
|
|
|
// Firefox at el. |
1411
|
|
|
else if (window.getSelection) |
1412
|
|
|
{ |
1413
|
|
|
var oCurSelection = window.getSelection(); |
1414
|
|
|
// Safari is special! |
1415
|
|
|
if (oCurSelection.setBaseAndExtent) |
1416
|
|
|
{ |
1417
|
|
|
var oLastChild = oCodeArea.lastChild; |
1418
|
|
|
oCurSelection.setBaseAndExtent(oCodeArea, 0, oLastChild, 'innerText' in oLastChild ? oLastChild.innerText.length : oLastChild.textContent.length); |
1419
|
|
|
} |
1420
|
|
|
else |
1421
|
|
|
{ |
1422
|
|
|
var curRange = document.createRange(); |
1423
|
|
|
curRange.selectNodeContents(oCodeArea); |
1424
|
|
|
|
1425
|
|
|
oCurSelection.removeAllRanges(); |
1426
|
|
|
oCurSelection.addRange(curRange); |
1427
|
|
|
} |
1428
|
|
|
} |
1429
|
|
|
|
1430
|
|
|
return false; |
1431
|
|
|
} |
1432
|
|
|
|
1433
|
|
|
// A function used to clean the attachments on post page |
1434
|
|
|
function cleanFileInput(idElement) |
1435
|
|
|
{ |
1436
|
|
|
// Simpler solutions work in Opera, IE, Safari and Chrome. |
1437
|
|
|
if (is_opera || is_ie || is_safari || is_chrome) |
1438
|
|
|
{ |
1439
|
|
|
document.getElementById(idElement).outerHTML = document.getElementById(idElement).outerHTML; |
1440
|
|
|
} |
1441
|
|
|
// What else can we do? By the way, this doesn't work in Chrome and Mac's Safari. |
1442
|
|
|
else |
1443
|
|
|
{ |
1444
|
|
|
document.getElementById(idElement).type = 'input'; |
1445
|
|
|
document.getElementById(idElement).type = 'file'; |
1446
|
|
|
} |
1447
|
|
|
} |
1448
|
|
|
|
1449
|
|
|
function applyWindowClasses(oList) |
1450
|
|
|
{ |
1451
|
|
|
var bAlternate = false; |
1452
|
|
|
oListItems = oList.getElementsByTagName("LI"); |
|
|
|
|
1453
|
|
|
for (i = 0; i < oListItems.length; i++) |
|
|
|
|
1454
|
|
|
{ |
1455
|
|
|
// Skip dummies. |
1456
|
|
|
if (oListItems[i].id == "") |
1457
|
|
|
continue; |
1458
|
|
|
oListItems[i].className = "windowbg" + (bAlternate ? "2" : ""); |
1459
|
|
|
bAlternate = !bAlternate; |
1460
|
|
|
} |
1461
|
|
|
} |
1462
|
|
|
|
1463
|
|
|
function reActivate() |
1464
|
|
|
{ |
1465
|
|
|
document.forms.postmodify.message.readOnly = false; |
1466
|
|
|
} |
1467
|
|
|
|
1468
|
|
|
function putOnSocks() |
1469
|
|
|
{ |
1470
|
|
|
var clicks = 0; |
1471
|
|
|
var firstClick = 0; |
1472
|
|
|
var lastClick = 0; |
1473
|
|
|
$('body').click(function() { |
1474
|
|
|
if (!firstClick) { |
1475
|
|
|
firstClick = Date.now(); |
1476
|
|
|
setTimeout(function() { |
1477
|
|
|
firstClick = 0; |
1478
|
|
|
lastClick = 0; |
1479
|
|
|
}, 1500) |
1480
|
|
|
} |
1481
|
|
|
lastClick = Date.now(); |
1482
|
|
|
|
1483
|
|
|
clicks++; |
1484
|
|
|
if (clicks >= 25 && lastClick - firstClick <= 15000) { |
1485
|
|
|
$('body, a').css({'cursor': 'url("data:image/png;base64,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"), auto'}) |
1486
|
|
|
} |
1487
|
|
|
}); |
1488
|
|
|
} |
1489
|
|
|
|
1490
|
|
|
// The actual message icon selector. |
1491
|
|
|
function showimage() |
1492
|
|
|
{ |
1493
|
|
|
document.images.icons.src = icon_urls[document.forms.postmodify.icon.options[document.forms.postmodify.icon.selectedIndex].value]; |
1494
|
|
|
} |
1495
|
|
|
|
1496
|
|
|
function pollOptions() |
1497
|
|
|
{ |
1498
|
|
|
var expire_time = document.getElementById('poll_expire'); |
1499
|
|
|
|
1500
|
|
|
if (isEmptyText(expire_time) || expire_time.value == 0) |
1501
|
|
|
{ |
1502
|
|
|
document.forms.postmodify.poll_hide[2].disabled = true; |
1503
|
|
|
if (document.forms.postmodify.poll_hide[2].checked) |
1504
|
|
|
document.forms.postmodify.poll_hide[1].checked = true; |
1505
|
|
|
} |
1506
|
|
|
else |
1507
|
|
|
document.forms.postmodify.poll_hide[2].disabled = false; |
1508
|
|
|
} |
1509
|
|
|
|
1510
|
|
|
function generateDays(offset) |
1511
|
|
|
{ |
1512
|
|
|
// Work around JavaScript's lack of support for default values... |
1513
|
|
|
offset = typeof(offset) != 'undefined' ? offset : ''; |
1514
|
|
|
|
1515
|
|
|
var days = 0, selected = 0; |
1516
|
|
|
var dayElement = document.getElementById("day" + offset), yearElement = document.getElementById("year" + offset), monthElement = document.getElementById("month" + offset); |
1517
|
|
|
|
1518
|
|
|
var monthLength = [ |
1519
|
|
|
31, 28, 31, 30, |
1520
|
|
|
31, 30, 31, 31, |
1521
|
|
|
30, 31, 30, 31 |
1522
|
|
|
]; |
1523
|
|
|
if (yearElement.options[yearElement.selectedIndex].value % 4 == 0) |
1524
|
|
|
monthLength[1] = 29; |
1525
|
|
|
|
1526
|
|
|
selected = dayElement.selectedIndex; |
1527
|
|
|
while (dayElement.options.length) |
1528
|
|
|
dayElement.options[0] = null; |
1529
|
|
|
|
1530
|
|
|
days = monthLength[monthElement.value - 1]; |
1531
|
|
|
|
1532
|
|
|
for (i = 1; i <= days; i++) |
|
|
|
|
1533
|
|
|
dayElement.options[dayElement.length] = new Option(i, i); |
1534
|
|
|
|
1535
|
|
|
if (selected < days) |
1536
|
|
|
dayElement.selectedIndex = selected; |
1537
|
|
|
} |
1538
|
|
|
|
1539
|
|
|
function toggleLinked(form) |
1540
|
|
|
{ |
1541
|
|
|
form.board.disabled = !form.link_to_board.checked; |
1542
|
|
|
} |
1543
|
|
|
|
1544
|
|
|
function initSearch() |
1545
|
|
|
{ |
1546
|
|
|
if (document.forms.searchform.search.value.indexOf("%u") != -1) |
1547
|
|
|
document.forms.searchform.search.value = unescape(document.forms.searchform.search.value); |
1548
|
|
|
} |
1549
|
|
|
|
1550
|
|
|
function selectBoards(ids, aFormID) |
1551
|
|
|
{ |
1552
|
|
|
var toggle = true; |
1553
|
|
|
var aForm = document.getElementById(aFormID); |
1554
|
|
|
|
1555
|
|
|
for (i = 0; i < ids.length; i++) |
|
|
|
|
1556
|
|
|
toggle = toggle & aForm["brd" + ids[i]].checked; |
1557
|
|
|
|
1558
|
|
|
for (i = 0; i < ids.length; i++) |
1559
|
|
|
aForm["brd" + ids[i]].checked = !toggle; |
1560
|
|
|
} |
1561
|
|
|
|
1562
|
|
|
function updateRuleDef(optNum) |
1563
|
|
|
{ |
1564
|
|
|
if (document.getElementById("ruletype" + optNum).value == "gid") |
1565
|
|
|
{ |
1566
|
|
|
document.getElementById("defdiv" + optNum).style.display = "none"; |
1567
|
|
|
document.getElementById("defseldiv" + optNum).style.display = ""; |
1568
|
|
|
} |
1569
|
|
|
else if (document.getElementById("ruletype" + optNum).value == "bud" || document.getElementById("ruletype" + optNum).value == "") |
1570
|
|
|
{ |
1571
|
|
|
document.getElementById("defdiv" + optNum).style.display = "none"; |
1572
|
|
|
document.getElementById("defseldiv" + optNum).style.display = "none"; |
1573
|
|
|
} |
1574
|
|
|
else |
1575
|
|
|
{ |
1576
|
|
|
document.getElementById("defdiv" + optNum).style.display = ""; |
1577
|
|
|
document.getElementById("defseldiv" + optNum).style.display = "none"; |
1578
|
|
|
} |
1579
|
|
|
} |
1580
|
|
|
|
1581
|
|
|
function updateActionDef(optNum) |
1582
|
|
|
{ |
1583
|
|
|
if (document.getElementById("acttype" + optNum).value == "lab") |
1584
|
|
|
{ |
1585
|
|
|
document.getElementById("labdiv" + optNum).style.display = ""; |
1586
|
|
|
} |
1587
|
|
|
else |
1588
|
|
|
{ |
1589
|
|
|
document.getElementById("labdiv" + optNum).style.display = "none"; |
1590
|
|
|
} |
1591
|
|
|
} |
1592
|
|
|
|
1593
|
|
|
function smc_resize(selector) |
1594
|
|
|
{ |
1595
|
|
|
|
1596
|
|
|
var allElements = []; |
1597
|
|
|
|
1598
|
|
|
$(selector).each(function(){ |
1599
|
|
|
|
1600
|
|
|
$thisElement = $(this); |
|
|
|
|
1601
|
|
|
|
1602
|
|
|
// Get rid of the width and height attributes. |
1603
|
|
|
$thisElement.removeAttr('width').removeAttr('height'); |
1604
|
|
|
|
1605
|
|
|
// Get the default vars. |
1606
|
|
|
$thisElement.basedElement = $thisElement.parent(); |
1607
|
|
|
$thisElement.defaultWidth = $thisElement.width(); |
1608
|
|
|
$thisElement.defaultHeight = $thisElement.height(); |
1609
|
|
|
$thisElement.aspectRatio = $thisElement.defaultHeight / $thisElement.defaultWidth; |
1610
|
|
|
|
1611
|
|
|
allElements.push($thisElement); |
1612
|
|
|
|
1613
|
|
|
}); |
1614
|
|
|
|
1615
|
|
|
$(window).resize(function(){ |
1616
|
|
|
|
1617
|
|
|
$(allElements).each(function(){ |
1618
|
|
|
|
1619
|
|
|
_innerElement = this; |
|
|
|
|
1620
|
|
|
|
1621
|
|
|
// Get the new width and height. |
1622
|
|
|
var newWidth = _innerElement.basedElement.width(); |
1623
|
|
|
var newHeight = (newWidth * _innerElement.aspectRatio) <= _innerElement.defaultHeight ? (newWidth * _innerElement.aspectRatio) : _innerElement.defaultHeight; |
1624
|
|
|
|
1625
|
|
|
// If the new width is lower than the "default width" then apply some resizing. No? then go back to our default sizes |
1626
|
|
|
var applyResize = (newWidth <= _innerElement.defaultWidth), |
1627
|
|
|
applyWidth = !applyResize ? _innerElement.defaultWidth : newWidth, |
1628
|
|
|
applyHeight = !applyResize ? _innerElement.defaultHeight : newHeight; |
1629
|
|
|
|
1630
|
|
|
// Gotta check the applied width and height is actually something! |
1631
|
|
|
if (applyWidth <= 0 && applyHeight <= 0) { |
1632
|
|
|
applyWidth = _innerElement.defaultWidth; |
1633
|
|
|
applyHeight = _innerElement.defaultHeight; |
1634
|
|
|
} |
1635
|
|
|
|
1636
|
|
|
// Finally resize the element! |
1637
|
|
|
_innerElement.width(applyWidth).height(applyHeight); |
1638
|
|
|
}); |
1639
|
|
|
|
1640
|
|
|
// Kick off one resize to fix all elements on page load. |
1641
|
|
|
}).resize(); |
1642
|
|
|
} |
1643
|
|
|
|
1644
|
|
|
$(function() |
1645
|
|
|
{ |
1646
|
|
|
$('.buttonlist > .dropmenu').each(function(index, item) |
1647
|
|
|
{ |
1648
|
|
|
$(item).prev().click(function(e) |
1649
|
|
|
{ |
1650
|
|
|
e.stopPropagation(); |
1651
|
|
|
e.preventDefault(); |
1652
|
|
|
|
1653
|
|
|
if ($(item).is(':visible')) |
1654
|
|
|
{ |
1655
|
|
|
$(item).css('display', 'none'); |
1656
|
|
|
|
1657
|
|
|
return true; |
1658
|
|
|
} |
1659
|
|
|
|
1660
|
|
|
$(item).css('display', 'block'); |
1661
|
|
|
$(item).css('top', $(this).offset().top + $(this).height()); |
1662
|
|
|
$(item).css('left', Math.max($(this).offset().left - $(item).width() + $(this).outerWidth(), 0)); |
1663
|
|
|
$(item).height($(item).find('div:first').height()); |
|
|
|
|
1664
|
|
|
}); |
1665
|
|
|
$(document).click(function() |
1666
|
|
|
{ |
1667
|
|
|
$(item).css('display', 'none'); |
1668
|
|
|
}); |
1669
|
|
|
}); |
1670
|
|
|
|
1671
|
|
|
putOnSocks(); |
1672
|
|
|
|
1673
|
|
|
// Generic confirmation message. |
1674
|
|
|
$(document).on('click', '.you_sure', function() |
1675
|
|
|
{ |
1676
|
|
|
var custom_message = $(this).attr('data-confirm'); |
1677
|
|
|
|
1678
|
|
|
return confirm(custom_message ? custom_message.replace(/-n-/g, "\n") : smf_you_sure); |
1679
|
|
|
}); |
1680
|
|
|
|
1681
|
|
|
// Generic event for smfSelectText() |
1682
|
|
|
$('.smf_select_text').on('click', function(e) { |
1683
|
|
|
|
1684
|
|
|
e.preventDefault(); |
1685
|
|
|
|
1686
|
|
|
// Do you want to target yourself? |
1687
|
|
|
var actOnElement = $(this).attr('data-actonelement'); |
1688
|
|
|
|
1689
|
|
|
return typeof actOnElement !== "undefined" ? smfSelectText(actOnElement, true) : smfSelectText(this); |
1690
|
|
|
}); |
1691
|
|
|
}); |
1692
|
|
|
|